package com.java.simple.study.io.nio;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

/**
 * @author zhoujunlin
 * @date 2023年04月19日 17:18
 * @desc
 */
@Slf4j
public class NIOClient {

    @SneakyThrows
    public static void main(String[] args) {
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.configureBlocking(false);
        socketChannel.connect(new InetSocketAddress("127.0.0.1", 9090));
        // 将channel注册到selector
        Selector selector = Selector.open();
        socketChannel.register(selector, SelectionKey.OP_CONNECT);
        while (true) {
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                if (selectionKey.isConnectable()) {
                    if (socketChannel.isConnectionPending()) {
                        socketChannel.finishConnect();
                        log.info("connected to server.");
                        socketChannel.register(selector, SelectionKey.OP_WRITE);
                    }
                } else if (selectionKey.isWritable()) {
                    ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
                    writeBuffer.put("Hello Server!".getBytes(StandardCharsets.UTF_8));
                    writeBuffer.flip();
                    socketChannel.write(writeBuffer);
                    selectionKey.interestOps(SelectionKey.OP_READ);
                } else if (selectionKey.isReadable()) {
                    ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                    while (socketChannel.read(readBuffer) > 0) {
                    }
                    readBuffer.flip();

                    String response = StandardCharsets.UTF_8.decode(readBuffer).toString();
                    log.info("接受到服务端的信息:{}", response);
                    selectionKey.interestOps(SelectionKey.OP_WRITE);
                }
                iterator.remove();
            }
            TimeUnit.MILLISECONDS.sleep(500);
        }
    }


}
